package parser;



import java.io.*;
import java.sql.*;
import java.text.DecimalFormat;
import java.util.*;

import org.geonames.*;


public class RadioParser {

	static HashMap<String, Integer> users;
	static HashMap<String, Integer> artists;
	static HashMap<String, Integer> artists2;
	static int numLines;
	static HashMap<String, String> timeCorrections;
	static ArrayList<String> stateList;
	static HashMap<String, Integer>songs;


	//REPLACED WITH A QUERY TO THE EXISTENT DB. 
	//Create the artists table
	/*	private static void topArtistsFirstStep(String filePath, String outPath) throws IOException{	
		artists = new HashMap<String, String>();
		File file = new File(filePath);
		FileWriter outFile = new FileWriter(outPath);
		Scanner scanner = new Scanner(file);
		BufferedWriter out = new BufferedWriter(outFile);
		String line;
		int count = 0;

		//First pass: build artists table
		while(scanner.hasNext()){
			count++;
			if(count%175000 == 0){
				System.out.println("Processed "+count/175000+" % of first pass");
			}

			line = scanner.nextLine();
			String pieces [] = line.split("\t");
			if(!pieces[1].equals("") || !pieces[2].matches(".*[&|ft|feat|-|:|;|(].*")){ //we have a code, let's add it to artists
				//System.out.println(count+" Inserting artist "+pieces[2]);
				if(artists.get(pieces[2])==null){
					if(pieces[1].equals(""))//put some dummy code
						artists.put(pieces[2], "NOCODE");
					else
						artists.put(pieces[2], pieces[1]);
					out.write(pieces[2] +"\t"+pieces[1]+"\n");

				}
			}
		}

		System.out.println("Processed 100% of first pass: artists dimension = "+ artists.keySet().size());
		scanner.close();
		out.close();
	}
	 */
	private static void buildArtistsTable(String filePath, String outPath) throws IOException{
		artists = new HashMap<String, Integer>();
		File file = new File(filePath);
		FileWriter outFile = new FileWriter(outPath);
		BufferedWriter out = new BufferedWriter(outFile);
		Scanner scanner = new Scanner(file);
		String line;
		int count = 0;

		while(scanner.hasNext()){
			count++;
			if(count%2950==0)
				System.out.println("Processed "+count/2950+" % of artists");
			line = scanner.nextLine();
			String pieces[] = line.split("\t");
			//System.out.println(pieces.length);
			if(pieces.length == 1){ //artist_code null: use name to discriminate
				if(!artists.containsKey(pieces[0])){
					artists.put(pieces[0], count);
					out.write(count+"\t"+"NOCODE"+"\t"+pieces[0]+"\n");
					//System.out.println(count+"\t"+"NOCODE"+"\t"+pieces[0]+"\n");
				}

			}
			else{ //artists 
				if(!artists.containsKey(pieces[1])){
					artists.put(pieces[1], count);
					out.write(count+"\t"+pieces[1]+"\t"+pieces[0]+"\n");
					//System.out.println(count+"\t"+pieces[1]+"\t"+pieces[0]+"\n");
				}


			}
		}
		out.close();
		System.out.println("Processed 100 % of artists");
	}

	private static void createPlaysTable(String filePath, String outPath) throws IOException{
		File file = new File(filePath);
		FileWriter outFile = new FileWriter(outPath);
		BufferedWriter out = new BufferedWriter(outFile);
		Scanner scanner = new Scanner(file);
		String line;
		int count = 0;
		while(scanner.hasNext()){
			count++;
			if(count%175000==0)
				System.out.println("Processed "+count/175000+" % of topArtists");
			line = scanner.nextLine();
			String pieces[] = line.split("\t");

			Integer user_code = users.get(pieces[0]);
			if(user_code != null){
				Integer artist_code;
				if(pieces[1].equals(""))
					artist_code = artists.get(pieces[2]);
				else
					artist_code = artists.get(pieces[1]);
				out.write(user_code.toString()+"\t"+artist_code.toString()+"\t"+pieces[3]+"\n");
			}
		}
		out.close();
		System.out.println("Processed 100 % of topArtists");
	}

	private static void createUsersTable(String filePath, String outPath) throws IOException{
		users = new HashMap<String, Integer>();
		File file = new File(filePath);
		FileWriter outFile = new FileWriter(outPath);
		BufferedWriter out = new BufferedWriter(outFile);
		Scanner scanner = new Scanner(file);
		String line;
		int count = 0;
		int count2= 0;
		while(scanner.hasNext()){
			count2++;
			if(count2%3600 == 0){
				System.out.println("Processed "+count2/3600+" % of users.tsv");
			}
			line = scanner.nextLine();
			String  pieces[] = line.split("\t");
			/*for(int i = 0; i < pieces.length; i++)
				System.out.println(i +" "+pieces[i]);*/
			if(users.get(pieces[0])==null){

				if(pieces.length >1){
					users.put(pieces[0], count);
					count++;

					out.write(users.get(pieces[0]).toString()+"\t"+pieces[1]+"\t"+pieces[2]+"\t"+pieces[3]+"\n");
				}
			}


			//System.out.println(users.get(pieces[0]).toString()+"\t"+pieces[1]+" "+pieces[2]+" "+pieces[3]+"\t"+pieces[4]+"\n");
		}
		out.close();
		System.out.println("Processed 100 % of users.tsv");
	}

	//private static void 


	private static void createTopArtistTable(String filePath, String outPath) throws IOException{
		buildArtistsTable("./src/data/artists.tsv", "./src/data/artistsTable.tsv");
		createPlaysTable(filePath, "./src/data/playsTable.tsv");

	}

	private static void loadTimeCorrections(String filePath, String statePath) throws FileNotFoundException{

		File file = new File(filePath);
		Scanner scanner = new Scanner(file);
		File stateFile = new File(statePath);
		Scanner stateScanner = new Scanner(stateFile);
		HashMap<String, String> stateCorrection = new HashMap<String, String>();
		timeCorrections = new HashMap<String, String>();
		while(stateScanner.hasNext()){
			String line = stateScanner.nextLine();
			String pieces[] = line.split("\t");
			/*for(int i = 0; i < pieces.length; i++)
				System.out.println(i+" "+pieces[i]);*/
			if(stateCorrection.get(pieces[2])==null){
				TimeZone tz;
				if(pieces.length > 4)
					stateCorrection.put(pieces[2], pieces[4]);
				else
					stateCorrection.put(pieces[2], "GMT");

			}

		}

		while(scanner.hasNext()){
			String line = scanner.nextLine();
			String pieces[] = line.split("\t");

			if(timeCorrections.get(pieces[0])==null){
				if(pieces.length>3)
					timeCorrections.put(pieces[0], stateCorrection.get(pieces[3]));
				else
					timeCorrections.put(pieces[0], "GMT");
			}
		}
		timeCorrections.put("0", "Europe/Berlin");

	}

	private static GregorianCalendar correcTime(int user, int year, int month, int day, int hour) throws FileNotFoundException{
		if(timeCorrections==null){
			loadTimeCorrections("./src/data/usersTime.tsv","./src/data/states.txt");
			System.out.println("timeCorrections loaded");
		}

		GregorianCalendar result = new GregorianCalendar(year, month, day, hour, 0);
		String id = timeCorrections.get(((Integer)user).toString());
		TimeZone tz = TimeZone.getTimeZone(id);
		//System.out.println(tz.getID()+" "+tz.getOffset(result.getTime().getTime()));
		result.setTimeInMillis(result.getTimeInMillis()+tz.getOffset(result.getTime().getTime()));
		return result;
	}

	private static void createTimeTable(String filePath, String outPath) throws IOException{
		File file = new File(filePath);
		FileWriter outFile = new FileWriter(outPath);
		BufferedWriter out = new BufferedWriter(outFile);
		Scanner scanner = new Scanner(file);
		String line;
		int count = 0;
		GregorianCalendar previousCal = null;
		int previousUser = -1;

		boolean print = false;
		int countHit = 0;
		ArrayList<Integer> countHours = new ArrayList<Integer>(); //this represent the count of songs for a single user
		for(int i = 0; i < 24; i++)
			countHours.add(0);
		while(scanner.hasNext()){
			count++;
			if(count % 190000==0)
				System.out.println("Processed "+count/190000+" % of times.tsv");

			line = scanner.nextLine();
			String pieces[] = line.split("\t");
			String time [] = pieces[1].split("[TZ]");
			String datepieces [] = time[0].split("-");
			String hourpieces [] = time[1].split(":");
			int year = Integer.parseInt(datepieces[0]);
			int month = Integer.parseInt(datepieces[1])-1;
			int day = Integer.parseInt(datepieces[2]);
			int hour = Integer.parseInt(hourpieces[0]);


			//GregorianCalendar cal = new GregorianCalendar(year,month, day, hour, 0);
			/*for(int i = 0; i < time.length; i++)
				System.out.println(i+" "+time[i]);*/
			//System.out.println(users.get(pieces[0])+"\t"++"\n");
			Integer user = users.get(pieces[0]);
			if(user!=null){
				GregorianCalendar cal = correcTime(user, year, month, day, hour);
				if(previousCal != null){
					if(user==previousUser){ //the user is the same, so I have to update the ArrayList
						if(cal.get(Calendar.YEAR)!=previousCal.get(Calendar.YEAR) || cal.get(Calendar.MONTH)!=previousCal.get(Calendar.MONTH) || cal.get(Calendar.DAY_OF_MONTH)!=previousCal.get(Calendar.DAY_OF_MONTH))
							countHit++;
						countHours.set(cal.get(Calendar.HOUR_OF_DAY), countHours.get(cal.get(Calendar.HOUR_OF_DAY))+1);
					}
					else{
						for(int i = 0; i < countHours.size(); i++){
							if(countHours.get(i) > 0){
								Double hoursMean = (double)countHours.get(i)/countHit;
								DecimalFormat one = new DecimalFormat("#,##0.0");
								out.write(user+"\t"+i+"\t"+one.format(hoursMean)+"\n");
								//System.out.println(user+"\t"+i+"\t"+one.format(hoursMean)+"\n");
							}
							countHours.set(i, 0);
						}
						countHit = 1;
						countHours.set(cal.get(Calendar.HOUR_OF_DAY), 1);
					}
				}
				else{
					countHours.set(cal.get(Calendar.HOUR_OF_DAY), 1);
					countHit++;
				}
				previousUser = user;
				previousCal = cal;

			}
		}

		out.close();
		System.out.println("Processed 100 % of times.tsv");
	}

	private static void geocoder(String filePath, String outPath) throws IOException{
		File file = new File(filePath);
		FileWriter outFile = new FileWriter(outPath);
		FileWriter errFile = new FileWriter("./src/data/geoErr.txt");
		BufferedWriter err = new BufferedWriter(errFile);
		BufferedWriter out = new BufferedWriter(outFile);
		Scanner scanner = new Scanner(file);
		String line;
		int count = 0;

		while(scanner.hasNext()){
			count++;
			if(count%3 == 0)
				System.out.println("Processed "+count/3+" % of countries");
			line = scanner.nextLine();

			//String line = "Kansas";
			ToponymSearchCriteria query = new ToponymSearchCriteria();
			query.setNameEquals(line);
			query.setStyle(Style.FULL);
			query.setMaxRows(1);
			ToponymSearchResult searchResult = null;
			try {
				WebService.setUserName("endriu");
				searchResult = WebService.search(query);

				for (Toponym toponym : searchResult.getToponyms()) {

					/*TimeZone tz = TimeZone.getDefault();
				tz.setID(toponym.getTimezone().getTimezoneId());
				GregorianCalendar now = new GregorianCalendar();
				now.setTimeZone(tz);
				now.get(Calendar.DST_OFFSET);
				System.out.println(now.get(Calendar.DST_OFFSET));*/

					//	System.out.println(toponym.getLatitude()+"\t"+toponym.getLongitude()+"\t"+line+"\t"+toponym.getContinentCode() +"\t"+ toponym.getTimezone().getTimezoneId()+"\n");
					out.write(toponym.getLatitude()+"\t"+toponym.getLongitude()+"\t"+line+"\t"+toponym.getContinentCode() +"\t"+ toponym.getTimezone().getTimezoneId()+"\n");

				}
			} catch (Exception e) {
				err.write(line+"\n");
			}
		}
		err.close();
		out.close();
		System.out.println("Processed 100 % of countries");
	}


	private static ArrayList<String> queryTypicalUser(String artistCode) throws SQLException{
		ArrayList<String> results = new ArrayList<String>();
		String driver = "org.sqlite.JDBC";
		Connection user_db_con;
		try
		{
			//Load the JDBC driver class dynamically.
			Driver d = (Driver)Class.forName(driver).newInstance();
			DriverManager.registerDriver(d);
		}
		catch(Exception e)
		{
			System.out.println("Error loading database driver: " + e.toString());
			return null;
		}

		//STEP 2: Create connection to database using database URL
		try
		{
			String url = "jdbc:sqlite:./src/data/lastfm.db";
			user_db_con = DriverManager.getConnection(url);

			//System.out.println("DB Connection OK");
		}
		catch(SQLException e)
		{
			System.out.println("Error creating connection: " + e.toString());
			return null;
		}
		//Step 3: create query for the database;
		Statement stmt;
		ResultSet res, res1, res2;
		String sql = "begin transaction;";
		stmt = user_db_con.createStatement();
		stmt.execute(sql);
		/*sql = "drop table nationalities;";
			stmt = user_db_con.createStatement();
			stmt.execute(sql);*/
		sql = "insert into nationalities select nationality from users where user_code in (select user_code from plays where artist_code == "+artistCode+");";
		stmt = user_db_con.createStatement();
		stmt.execute(sql);
		/*sql = "create index nat on nationalities(nationality);";
			stmt = user_db_con.createStatement();
			stmt.execute(sql);*/
		sql = "select distinct N.nationality, (select count(*) from nationalities as N1 where N1.nationality == N.nationality) as listeners from nationalities as N order by listeners desc limit 3;";
		stmt = user_db_con.createStatement();
		res = stmt.executeQuery(sql);
		sql = "insert into ages select age from users where user_code in (select user_code from plays where artist_code == "+artistCode+");";
		stmt = user_db_con.createStatement();
		stmt.execute(sql);
		/*sql = "create index a on ages(age);";
			stmt = user_db_con.createStatement();
			stmt.execute(sql);*/
		sql = "select distinct A.age, (select count(*) from ages as A1 where A1.age == A.age) as listeners from ages as A order by listeners desc limit 10;";
		stmt = user_db_con.createStatement();
		res1 = stmt.executeQuery(sql);
		sql = "insert into sexes select sex from users where user_code in (select user_code from plays where artist_code == "+artistCode+");";
		stmt = user_db_con.createStatement();
		stmt.execute(sql);
		sql = "select distinct S.sex, (select count(*) from sexes as S1 where S1.sex == S.sex) as listeners from sexes as S order by listeners desc limit 2;";
		stmt = user_db_con.createStatement();
		res2 = stmt.executeQuery(sql);
		/*sql = "drop table nationalities;";
			stmt = user_db_con.createStatement();
			stmt.execute(sql);*/
		sql = "delete from nationalities;";
		stmt = user_db_con.createStatement();
		stmt.execute(sql);
		sql = "delete from ages;";
		stmt = user_db_con.createStatement();
		stmt.execute(sql);
		sql = "delete from sexes;";
		stmt = user_db_con.createStatement();
		stmt.execute(sql);
		sql = "commit;";
		stmt = user_db_con.createStatement();
		stmt.execute(sql);

		//STEP 4: Read results
		try
		{
			String nationality;
			//int numListeners;
			while(res.next())
			{
				nationality = res.getString("nationality");
				//numListeners = res.getInt("listeners");
				//System.out.println("-> "+ user_code +" "+plays );
				results.add(nationality);
			}
			String age;
			while(res1.next())
			{
				age = res1.getString("age");
				//numListeners = res.getInt("listeners");
				//System.out.println("-> "+ user_code +" "+plays );
				results.add(age);
			}
			String sex;
			while(res2.next())
			{
				sex = res2.getString("sex");
				//numListeners = res.getInt("listeners");
				//System.out.println("-> "+ user_code +" "+plays );
				results.add(sex);
			}
		}
		catch(Exception e)
		{
			System.out.println("Error processing results: " + e.toString());
			try
			{
				res.close();
				stmt.close();
				user_db_con.close();
			}
			catch(Exception ex)
			{
			}
			return null;
		}
		//STEP 5: close conection
		try{
			res.close();
			stmt.close();
			user_db_con.close();
		}
		catch(Exception e){
			System.out.println("Error in closing the connection");
		}
		return results;
	}


	private static void createTypicalUserTable(String filePath, String outPath) throws IOException, SQLException{
		File file = new File(filePath);

		FileWriter outFile = new FileWriter(outPath);
		BufferedWriter out = new BufferedWriter(outFile);

		Scanner scanner = new Scanner(file);
		String line;
		int count = 0;

		while (scanner.hasNext()){
			line = scanner.nextLine();
			count++;
			if(count%1600==0)
				System.out.println("Processed "+count/1600+" % of TypicalUsers");
			ArrayList<String> queryResults = queryTypicalUser(line);
			String result = new String(line+"\t");
			if(queryResults.size() > 0){
				for(int i = 0; i < queryResults.size()-1; i++)
					result = result.concat(queryResults.get(i)+",");
				result = result.concat(queryResults.get(queryResults.size()-1)+"\n");
			}
			else{
				result.concat(""+"\n");
			}
			out.write(result);
			System.out.println(result);

		}
		out.close();

		System.out.println("Processed 100 % of TypicalUsers");
	}

	private static void loadStates(String filePath) throws FileNotFoundException{
		File file = new File(filePath);
		Scanner scanner = new Scanner(file);
		String line;
		stateList = new ArrayList<String>();
		while(scanner.hasNext()){
			line = scanner.nextLine();
			String pieces[] = line.split("\t");
			if(!stateList.contains(pieces[2]))
				stateList.add(pieces[2]);

		}
		System.out.println("State loading complete");
	}

	private static void correctTypicalUserTable(String filePath, String outPath) throws IOException, SQLException{
		File file = new File(filePath);
		File tempReadFile = new File("./src/data/temp.tsv");
		FileWriter outFile = new FileWriter(outPath);
		BufferedWriter out = new BufferedWriter(outFile);
		Scanner scanner = new Scanner(file);
		FileWriter tempFile = new FileWriter("./src/data/temp.tsv");
		BufferedWriter temp = new BufferedWriter(tempFile);
		String line;
		int count = 0;
		if(stateList == null){
			loadStates("./src/data/states.txt");
			/*for(String s : stateList)
				System.out.println(s);
			return;*/
		}

		//correct bug that made me print in the same line two artists, if the first one had no data on typical users
		while(scanner.hasNext()){
			line = scanner.nextLine();
			String pieces[] = line.split("\t");
			if(pieces.length>2){
				temp.write(pieces[0]+"\n");
				String newLine = new String(pieces[1]);
				for(int i = 2; i < pieces.length; i++)
					newLine = newLine.concat("\t"+pieces[i]);
				newLine = newLine.concat("\n");
				temp.write(newLine);
			}
			else{
				temp.write(line+"\n");
			}
		}
		System.out.println("Messed up lines fully corrected");
		temp.close();
		Scanner tempScanner = new Scanner(tempReadFile);
		while(tempScanner.hasNext()){
			count++;
			if(count%1600==0)
				System.out.println("Corrected "+count/1600+" % of TypicalUsers.tsv");
			line = tempScanner.nextLine();
			String pieces[] = line.split("\t");
			//Switch code from artist_code to mb_code: need query to db
			String driver = "org.sqlite.JDBC";
			Connection user_db_con;
			try
			{
				//Load the JDBC driver class dynamically.
				Driver d = (Driver)Class.forName(driver).newInstance();
				DriverManager.registerDriver(d);
			}
			catch(Exception e)
			{
				e.printStackTrace();
				return;
			}

			//STEP 2: Create connection to database using database URL

			String url = "jdbc:sqlite:./src/data/lastfm.db";
			user_db_con = DriverManager.getConnection(url);

			//System.out.println("DB Connection OK");

			//Step 3: create query for the database;
			Statement stmt;
			ResultSet res;

			String sql = "select mb_code from artists where artist_code == "+pieces[0]+";";
			stmt = user_db_con.createStatement();
			res = stmt.executeQuery(sql);
			String mb_code = null;

			//STEP 4: Read results



			while(res.next())
			{
				mb_code = res.getString("mb_code");
				//numListeners = res.getInt("listeners");
				//System.out.println("-> "+ user_code +" "+plays );

			}



			//STEP 5: close conection
			try{
				res.close();
				stmt.close();
				user_db_con.close();
			}
			catch(Exception e){
				System.out.println("Error in closing the connection");
			}


			//System.out.println(pieces[0] +" becames "+mb_code);
			try{
				Integer.parseInt(mb_code);
				System.err.println("MB_CODE NUMERIC "+ pieces[0]);
			}
			catch(NumberFormatException e){}
			String result = new String(mb_code);


			if(pieces.length>1){
				String data [] = pieces[1].split(",");
				ArrayList<String> dataGood = new ArrayList<String>();
				//correct states with comma and nonexistent values
				for(int i = 0; i < data.length; i++){
					try{
						Integer.parseInt(data[i]);
						if(Integer.parseInt(data[i])>200){
							System.err.print("WARNING "+data[i]+" ");
							System.out.println(result);
							//return;
						}
						dataGood.add(data[i]);

					}
					catch(NumberFormatException e){ //the data is not a number, let's check if is a nationality or a sex
						if(data[i].equals("m") || data[i].equals("f"))
							dataGood.add(data[i]);
						else if(!data[i].equals("")){
							String nation = data[i];
							if(nation.equals("Congo")){
								if(stateList.contains(nation.concat(","+data[i+1]))){
									nation = nation.concat(","+data[i+1]);
									i++;
								}
							}
							else{
								while(!stateList.contains(nation)){
									nation = nation.concat(","+data[++i]);

								}
							}
							//System.out.println(nation);
							dataGood.add(nation);
						}
					}
				}
				for(String s : dataGood)
					result = result.concat("\t"+s);
			}
			result = result.concat("\n");
			//System.out.println(result);
			out.write(result);
		}
		tempReadFile.delete();
		out.close();
		System.out.println("Corrected 100 % of TypicalUsers.tsv");
	}


	private static void createSongDataset(String filePath,String outPath) throws IOException{
		File file = new File(filePath);
		FileWriter outFile = new FileWriter(outPath);
		FileWriter songsFile = new FileWriter("./src/data/songs.tsv");
		BufferedWriter outSongs = new BufferedWriter(songsFile);
		FileWriter artistFile = new FileWriter("./src/data/artists2.tsv");
		BufferedWriter outArtists = new BufferedWriter(artistFile);
		BufferedWriter out = new BufferedWriter(outFile);
		Scanner scanner = new Scanner(file);
		String line;
		int count = 0;
		int count2 =0;
		if(users == null || !users.values().contains("user_000001"))
			createUsersTable("/Users/endriu/Desktop/lastfm-dataset-1K/userid-profile.tsv","./src/data/usersTime.tsv");


		//STEP 1: create table with songs and table of artists
		songs = new HashMap<String, Integer>();
		artists2 = new HashMap<String, Integer>();
		int countArtists = 0;
		while(scanner.hasNext()){
			count++;
			if(count%190000==0)
				System.out.println("loaded "+count/190000+" % of songs & artists");
			line = scanner.nextLine();
			String pieces [] = line.split("\t");
			if(pieces.length>4 && !pieces[4].equals(""))
				if(songs.get(pieces[4])==null){
					songs.put(pieces[4], count2++);
					if(artists2.get(pieces[2])==null){
						//TODO look for artist_name in lastFM API
						artists2.put(pieces[2], ++countArtists);
						outArtists.write(artists2.get(pieces[2])+"\t"+pieces[2]+"\t"+pieces[3].toLowerCase()+"\n");
						//System.out.println("Artist: "+countArtists+"\t"+pieces[2]+"\t"+pieces[3].toLowerCase()+"\n");
					}
					outSongs.write(count2+"\t"+artists2.get(pieces[2])+"\t"+pieces[4]+"\t"+pieces[5].toLowerCase()+"\n");
					//System.out.println("Songs: "+count2+"\t"+artists2.get(pieces[2])+"\t"+pieces[4]+"\t"+pieces[5].toLowerCase()+"\n");
				}
		}
		outArtists.close();
		outSongs.close();
		System.out.println("songs & artists completed");
		scanner.close();
		scanner = new Scanner(file);
		
		
		int previousUser = -1;
		Integer user;
		count =0; 
		HashMap<Integer, Integer> songPlays = new HashMap<Integer, Integer>();
		while(scanner.hasNext()){
			
			count++;
			if(count%190000==0)
				System.out.println("Processed "+count/190000+" % of songPlays");
			line = scanner.nextLine();
			
			String pieces[] = line.split("\t");
			if(pieces.length>4 && !pieces[4].equals("")){
				user = users.get(pieces[0]);
				if(user == null) continue;
				if(previousUser == -1 || (int)user==previousUser){
					int codeSong = songs.get(pieces[4]);
					if(songPlays.get(codeSong)==null)
						songPlays.put(codeSong, 1);
					else
						songPlays.put(codeSong, songPlays.get(codeSong)+1);
				}
				else{
					ArrayList<Integer> keys = new ArrayList<Integer>(songPlays.keySet());
					ArrayList<Integer> values = new ArrayList<Integer>(songPlays.values());
					for(int i = 0; i< keys.size(); i++){
						out.write(((Integer)previousUser).toString()+"\t"+keys.get(i).toString()+"\t"+values.get(i).toString()+"\n");
						//System.out.println(((Integer)previousUser).toString()+"\t"+keys.get(i).toString()+"\t"+values.get(i).toString()+"\n");
						songPlays = new HashMap<Integer, Integer>();
					}
				}
				previousUser = user;

			}
		}
		ArrayList<Integer> keys = new ArrayList<Integer>(songPlays.keySet());
		ArrayList<Integer> values = new ArrayList<Integer>(songPlays.values());
		for(int i = 0; i< keys.size(); i++){
			out.write(((Integer)previousUser).toString()+"\t"+keys.get(i).toString()+"\t"+values.get(i).toString()+"\n");
			//System.out.println(((Integer)previousUser).toString()+"\t"+keys.get(i).toString()+"\t"+values.get(i).toString()+"\n");
			//songPlays = new HashMap<Integer, Integer>();
		}
		out.close();
		System.out.println("Processed 100 % of songPlays");
	}


	public static void main(String [] args) throws IOException, SQLException{
		//System.out.println(args[0] + " " + args[1]);
		GregorianCalendar start = new GregorianCalendar();
		//createUsersTable(args[1], "./src/data/users.tsv");
		//createTopArtistTable(args[0], "./src/data/topArtists.tsv");
		//createUsersTable(args[2], "./src/data/usersTime.tsv");
		//createTimeTable(args[3], "./src/data/times.tsv");
		//geocoder("./src/data/countries.txt", "./src/data/states2.txt");
		//createTypicalUserTable("./src/data/artistCodes","./src/data/typicalUserTable.tsv");
		//correctTypicalUserTable("./src/data/typicalUserTable.tsv", "./src/data/typicalUserTable_final.tsv");
		createSongDataset("/Users/endriu/Desktop/lastfm-dataset-1K/timeArtists.tsv","./src/data/songsTable.tsv");
		
		//TODO sanitize names... must discover more
		
		GregorianCalendar stop = new GregorianCalendar();
		long time = stop.getTimeInMillis() - start.getTimeInMillis();
		int hours = (int)(time/3600000);
		time -=(hours*3600000);
		int minutes = (int)(time/60000);
		time -=(minutes*60000);
		int seconds = (int)(time/1000);
		System.out.println("ALL OK\nTime for conversion: "+hours+" hours, "+minutes+" minutes, "+seconds+" seconds");


	}
}
